//
//  Account.swift
//  home
//
//  Created by Yun Zeng on 2019/8/4.
//  Copyright © 2019 Yun Zeng. All rights reserved.
//

import Foundation

#if os(iOS)
import UIKit
#endif

// MARK: 登录设备类型
var DevType: String {
    #if os(iOS)
    let device = UIDevice.current
    if device.model == "iPhone" {
        return "phone"
    } else if device.model == "iPad" && device.systemName == "iOS" {
        return "pad"
    } else {
        return "pc"
    }
    #else
        return "pc"
    #endif
}

// MARK: 用户信息
class Membership: Codable {
    // 注册账号与密码
    var account: String = ""
    var password: String = ""
    
    // 用户ID与登录Token
    var uuid: String?
    var token: String?
    
    // 用户名与头像
    var name: String?
    var icon: String?
    
    // 关联家庭
    struct Home: Codable {
        var home: String
        var role: String
    }
    
    var homes: [Home]?
}

extension Membership: CustomStringConvertible {
    var description: String {
        let data = try! JSONEncoder().encode(self)
        return String(data: data, encoding: .utf8)!
    }
}


protocol AccountDelegate {
    func AccountDidLogin()
    func AccountDidLogout(state: String)
}

extension Account {
    static let instance: Account = {
        return Account()
    } ()
}

class Account {
    var membership: Membership
    var client: CloudClient
    
    let configFile = {
        return Storage.Path.appendingPathComponent("account").appendingPathExtension("json")
    } ()
    
    private init() {
        self.client = CloudClient.instance
        if let data = try? Data(contentsOf: configFile),
            let membership = try? JSONDecoder().decode(Membership.self, from: data)
        {
            self.membership = membership
        } else {
            self.membership = Membership()
        }
        _ = self.client.addObserver(path: CloudMessage.Path.membership, controller: self)
        
        if self.enable {
            self.client.enable()
            if let home = self.membership.homes?.first {
                HomeManager.instance.setCurrentHome(id: home.home)
            }
        }
    }
    
    // 登录
    func login(account: String, password: String) -> Bool {
        if account == "" || password == "" {
            return false
        }
        self.membership.account = account
        self.membership.password = password
        self.client.enable()
        return true
    }
    
    // MARK: 登录
    struct LoginInfo: Codable {
        var account: String?
        var password: String?
        var id: String?
        var session: String?
        var dev_t: String?
    }
    
    func login() {
        if self.membership.uuid == nil || self.membership.uuid == "" {
            let data = LoginInfo(account: self.membership.account, password: self.membership.password, id: nil, session: nil, dev_t: DevType)
            let msg = CloudMessage(path: CloudMessage.Path.login, method: .post, object: data)
            self.client.sendMessage(msg: msg)
        } else {
            let data = LoginInfo(account: nil, password: nil, id: self.membership.uuid, session: self.membership.token, dev_t: DevType)
            let msg = CloudMessage(path: CloudMessage.Path.login, method: .post, object: data)
            self.client.sendMessage(msg: msg)
        }
    }
    
    // MARK: 退出登录
    struct LogoutInfo: Codable {
        var id: String
        var dev_t: String
        var data: String
    }

    func logout() -> Bool {
        if let id = self.membership.uuid {
            let info = LogoutInfo(id: id, dev_t: DevType, data: "")
            let msg = CloudMessage(path: CloudMessage.Path.logout
                , method: .post, object: info)
            self.client.sendMessage(msg: msg)
        }
        self.membership.password = ""
        self.membership.uuid = nil
        self.membership.token = nil
        self.membership.homes = nil
        self.saveConfig()
        return true
    }
    
    // 保存配置信息
    func saveConfig() {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        if let data = try? encoder.encode(self.membership) {
            Logger.Info("account info: \n\(String(data: data, encoding: .utf8)!)")
            try! data.write(to: self.configFile)
        }
    }

    var enable: Bool {
        get {
            if self.membership.account == "" || self.membership.password == "" {
                return false
            }
            return true
        }
    }
    
    // MARK: 监听账号管理状态
    var observers = Dictionary<String, AccountDelegate>()
    func addObserver(identify: String, observer: AccountDelegate) {
        self.observers[identify] = observer
    }
    func removeObserver(identify: String) -> Bool {
        if let _ = self.observers.removeValue(forKey: identify) {
            return true
        }
        return false
    }
    
    // APNS 推送
    var apnsToken: String = "" {
        didSet {
            if self.client.state == .transfer {
                self.pushAPNSToken()
            }
        }
    }
    
    func pushAPNSToken() {
        struct PushInfo: Codable {
            var topic: String
            var apns: String
            var dev_t: String
        }
        let info = PushInfo(topic: Bundle.main.bundleIdentifier!, apns: self.apnsToken, dev_t: DevType)
        let msg = CloudMessage(path: CloudMessage.Path.apnsInfo, method: .post, object: info)
        self.client.sendMessage(msg: msg)
    }
    
}

extension Account: CloudMessageHandler {
    struct LoginAck: Codable {
        var id: String
        var token: String
        var name: String
        var icon: String
        var homes: [Membership.Home]?
    }
    
    func handle(msg: CloudMessage) -> CloudMessageError {
        if msg.path == CloudMessage.Path.login {
            if msg.state != "ok" {
                self.client.disable()
                self.membership.password = ""
                self.membership.uuid = nil
                self.membership.token = nil
                self.membership.homes = nil
                self.saveConfig()
                for observer in self.observers {
                    observer.value.AccountDidLogout(state: msg.state ?? "ok")
                }
                return .success
            }
            
            guard let data = msg.data else {
                return .jsonFormatError
            }
            
            guard let ack = try? JSONDecoder().decode(LoginAck.self, from: data) else {
                return .jsonFormatError
            }
            
            self.membership.uuid = ack.id
            self.membership.token = ack.token
            self.membership.name = ack.name
            self.membership.icon = ack.icon
            self.membership.homes = ack.homes
            self.saveConfig()
            if let home = self.membership.homes?.first {
                HomeManager.instance.setCurrentHome(id: home.home)
            }
            
            CloudClient.instance.state = .transfer
            
            if self.apnsToken != "" {
                self.pushAPNSToken()
            }
            
            for observer in self.observers {
                observer.value.AccountDidLogin()
            }
            return .success
        }
        
        // 退出登录返回消息
        if msg.path == CloudMessage.Path.logout {
            self.client.disable()
            for observer in self.observers {
                observer.value.AccountDidLogout(state: msg.state ?? "ok")
            }
            
            if msg.state != "ok" {
                self.client.disable()
                self.membership.password = ""
                self.membership.uuid = nil
                self.membership.token = nil
                self.membership.homes = nil
                self.saveConfig()
                return .success
            }
        }
        return .success
    }
    
    func clientStateChange(state: CloudClient.State) {
        if state == .verify {
            self.login()
        }
    }
}














